home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / WLIB.ZIP / WSTR.DOC < prev    next >
Encoding:
Text File  |  1993-02-12  |  40.7 KB  |  1,043 lines

  1. Wheaton Strings library documentation
  2.  
  3. October 10, 1989
  4. February 20, 1991 (minor update)
  5. May 15, 1992 (minor update)
  6. October 20, 1992 (minor update)
  7. January 27, 1993 (add String40 and String120 - fix some documentation bugs)
  8.  
  9. Copyright (c) 1992, 1993 by Paul Wheaton
  10.  
  11. Note that this documentation does not cover all of the features of the
  12. provided in this library.  For that, you will have to look at the header files.
  13.  
  14. The Wheaton Libraries are shareware. Anyone may use the libraries provided
  15. that they do not change them.  If you want to change them or if you want
  16. phone support from me, you must pay $50. This in the hope that the hundreds
  17. of vendors that are creating their own string libraries can go with just
  18. one - I'm pretty tired of getting a library in that seems like it will be
  19. pretty cool, just to find out that it uses the same identifiers as
  20. something else and there are then link conflicts.
  21.  
  22. For those programmers that never read documentation but have
  23. mysteriously made it this far, just look quickly at section 1.1.4 and
  24. 5.1.  To make these libraries available, you need to include
  25. <Strings.h> link with WLIB.LIB and FATAL.OBJ (or WW.LIB which includes
  26. a different FATAL.OBJ).
  27.  
  28. This Strings library, consisting of one class and a few independent
  29. functions, provides an easier, more intuitive way to manipulate
  30. strings.  By including this stuff into your programs you can use (or
  31. create!) functions that do not need chunks of memory pre-allocated for
  32. them.  Concatenation is done with "+" or "+=" instead of "strcat".
  33. Comparison is done with "==", "!=", "<", etc. instead of "strcmp".
  34. Source ends up being more readable, and less verbose.  Many common
  35. string manipulation errors are completely eliminated.  For programmers
  36. new to "C", these libraries provide more functionality with fewer
  37. operators to memorize, thus reducing the dreaded learning curve.
  38.  
  39. (note - there is now more than one class, but you may treat the class
  40. "String" as if it were just one.  Later, when you have more experience, you
  41. can use the classes String40 and String120 for optimization)
  42.  
  43. Strings are automatically converted from type String to char* and back
  44. as needed.  The two types can often be mixed to give the same results.
  45.  
  46.  
  47.       Strings
  48. 1       Advantages over C
  49. 1.1       for programmers new to C
  50. 1.1.1       less to memorize
  51. 1.1.2       more intuitive
  52. 1.1.3       similar to other languages
  53. 1.1.4       faster to learn
  54. 1.2       for old C programmers
  55. 1.2.1       less to type
  56. 1.2.2       less worry about low level stuff: concentrate more on program
  57. 1.2.3       more readable
  58. 1.2.4       eliminate overflow errors
  59. 1.2.5       faster executable
  60.               length does not need to be calculated
  61. 1.2.6       use less memory
  62.               don't need to allocate memory to cover "worst case"
  63. 1.2.7       functions that are more independent (don't need storage space)
  64. 2       Disadvantages from C
  65. 2.1       speed overhead
  66.             allocating memory in the heap at creation and appending
  67. 2.2       storage overhead
  68.             storing length and extra pointers
  69. 3       A little bit about how this works
  70. 4       Implementing this with char* for optimal performance
  71. 5       Functions
  72. 5.1       String class member functions
  73. 5.1.1       declaring a String
  74. 5.1.1.1       based on a given string constant or char*
  75. 5.1.1.2       based on a character
  76. 5.1.1.3       based on another String
  77. 5.1.1.4       without initialization
  78. 5.1.1.5       extra allocation
  79. 5.1.2       Length() or Size()
  80. 5.1.3       + (concatenation)
  81. 5.1.4       += (appending form of concatenation)
  82. 5.1.5       = (assignment) and conversions
  83. 5.1.6       ==,!=,<,>,<=,>= (comparison)
  84. 5.1.7       () or At() (retrieving substrings)
  85. 5.1.7.1       Before(), Through(), From() and After()
  86. 5.1.8       [] (String char reference)
  87. 5.1.9       Left(), Right(), Center(), Just()  (justification)
  88. 5.1.10      Capacity() (report current allocation)
  89. 5.1.11      ReAlloc() (change capacity)
  90. 5.1.12      ToLower() (force all upper case letters to lower case)
  91. 5.1.13      ToUpper() (force all lower case letters to upper case)
  92. 5.1.14      Index() (find the index of a char)
  93. 5.1.15      Insert() (insert a char or a sting into the string)
  94. 5.1.16      Delete() (delete characters from the string)
  95. 5.2       non-member functions
  96. 5.2.1       Str() (convert integers to String)
  97. 5.2.2       Form() (convert reals to a String using a format)
  98. 5.2.3       StringOf() (return a string of chars)
  99. 5.2.4       Spaces() (return a String of a certain number of spaces)
  100. 5.2.5       LeftText(), RightText(), CenterText(), JustText()
  101.  
  102.  
  103.  
  104. 1 Advantages over C
  105.  
  106.   I hope to show that using these String libraries in C++ is a great deal
  107.   easier than using the ANSI C string libraries or any string library that
  108.   could possibly be written in C.  It is my opinion that productivity in
  109.   string manipulation development will increase by a factor of four for
  110.   those application programmers that use this library.
  111.  
  112. 1.1 for programmers new to C
  113.  
  114.   Any time that you move to a new language there will be a learning curve.
  115.   C is notorious for being too terse and, thus, hard to read and tougher to
  116.   learn.  Much of this has to do with being a "mid level language":  Easier
  117.   to work with than assembly yet harder than "high level languages" such as
  118.   Pascal or FORTRAN.  C gains you a great deal of portability and runtime
  119.   effeciency over most "high level languages".  C++ with a healthy set of
  120.   libraries provides all of the advantages of C coupled with the advantages
  121.   of a high level language.  This library should make string manipulation
  122.   easier than not only C, but FORTRAN, Pascal, BASIC, LISP or Modula-2.  A
  123.   programmer new to this library will probably find all of the string
  124.   manipulation features that they appreciated most in their favorite
  125.   languages and then some new twists that will make their programming lives
  126.   even easier.
  127.  
  128. 1.1.1 less to memorize
  129.  
  130.   C++ cures some of the idiosyncrasies of C that directly effect
  131.   string manipulation libraries, one of the worst being the pointer to
  132.   a character concept.  In order for a programmer to keep from getting
  133.   into trouble when manipulating strings in C, they must memorize how
  134.   the compiler handles them (the strings):  C Strings are an array of
  135.   characters terminated by a null character; strings are referenced by
  136.   a pointer to the first element of the string; runtime range checking
  137.   is not standard and is performed with library routines when the size
  138.   of the string is passed.
  139.  
  140.   In this library, how the String is actually stored and manipulated
  141.   is hidden from the applications programmer.  Runtime range checking
  142.   is performed by the library so the applications programmer can
  143.   concentrate on their application rather than monitor the size of
  144.   their strings and make sure everything will fit.  Since string
  145.   manipulation using this library is similar to working with numbers
  146.   in C or C++, all of the exceptions for plain C string handling never
  147.   have to be learned.
  148.  
  149. 1.1.2 more intuitive
  150.  
  151.   ANSI C maintains a great deal of exceptions when it comes to string
  152.   handling.  For example, if you have two strings, S1 and S2,
  153.   assignment of one from the other does not result in two identical
  154.   copies of the string, it results in two pointers pointing to the
  155.   same string:  Modifying one effects the other.  Generally, when an
  156.   assignment is made such as X=Y, the contents of X are separate from
  157.   Y yet the same.  This library supports the more intuitive assignment
  158.   operation as well as other operators and functions that any string
  159.   library *ought* to have.
  160.  
  161. 1.1.3 similar to other languages
  162.  
  163.   Of course, all of the functions and operators available in C are
  164.   also available in C++.  Many of them (C functions) will work with
  165.   the String type as well as good ole char*.
  166.  
  167.   In Turbo Pascal
  168.  
  169.     Var S1,S2:String;
  170.     Begin
  171.       S1:="oatmeal";
  172.       S2:="I like "+S1+".";
  173.     End;
  174.  
  175.   In BASIC
  176.  
  177.     550 S1$="oatmeal"
  178.     560 S2$="I like "+S1$+"."
  179.  
  180.   In FORTRAN
  181.  
  182.     char S1*8
  183.     char S2*16
  184.     S1='oatmeal'
  185.     S2='I like ' // S1 // '.'
  186.  
  187.   In C  (or C++ without this library)
  188.  
  189.     char* S1="oatmeal";
  190.     char S2[16];
  191.     strcpy(S2,"I like ");
  192.     strcat(S2,S1);
  193.     strcat(S2,".");
  194.  
  195.   or...
  196.  
  197.     char* S1="oatmeal";
  198.     char S2[16];
  199.     sprintf(S2,"I like %s.",S1);
  200.  
  201.   With this library...
  202.  
  203.     String S1="oatmeal";
  204.     String S2="I like "+S1+".";
  205.  
  206.   As I hope you can see, this library's operators and functions
  207.   provide a string manipulation library that implements the best and
  208.   most common parts of other languages.  You should find that using
  209.   this library with C++ is a great deal simpler, more readable and
  210.   more powerful than what you were using before.
  211.  
  212. 1.1.4 faster to learn
  213.  
  214.   Given the aforementioned points, it ought to be clear that learning
  215.   how to use this library will take a small fraction of the time it
  216.   would take to learn ANSI C string manipulation.  For most
  217.   applications all you need to know is that "String" is the
  218.   constructor, "=" is assignment and "+" is concatenation.  Also,
  219.   anything that *seems* like it should work, probably will; if it
  220.   *seems* like there should be a function to handle a certain case,
  221.   there probably is.
  222.  
  223. 1.2 for old C programmers
  224.  
  225.   Don't fret!  This library is completely compatible with the old
  226.   char* stuff.  You only need to use it when it's convenient to you.
  227.   After a while, I hope that you'll use it 99% of the time (yes there
  228.   are a few times when using char* could save some execution time or
  229.   storage space). For the most part, I think you'll find that this
  230.   stuff cuts your development time to a third (maybe a quarter!) of
  231.   what it used to be in string manipulation.
  232.  
  233. 1.2.1 less to type
  234.  
  235.   Since C++ allows access to define operators, then the ANSI functions
  236.   to do string comparisons and the like can be circumvented for the
  237.   more convenient notations.
  238.  
  239.   Notation for assignment
  240.  
  241.     in C  :  strncpy(S1,S2,sizeof(S1));
  242.     in C++:  S1=S2;
  243.  
  244.   Concatenation
  245.  
  246.     in C  :  strncat(S1,strncat(S2,S3,sizeof(S2)),sizeof(S1));
  247.     or    :  sprintf(S1,"%s%s%s",S1,S2,S3);
  248.     in C++:  S1+=S2+S3;
  249.  
  250.   Comparison
  251.  
  252.     in C  :  strcmp(S1,S2)<0
  253.     in C++:  S1<S2
  254.  
  255. 1.2.2 less worry about low level stuff: concentrate more on program
  256.  
  257.   Without this library there is the frequent need of application programmer
  258.   range checking:  Making sure that arrays are declared of sufficient size;
  259.   indexing is within bounds; using the appropriate function/operator on the
  260.   appropriate structure (such as sizeof on char* vs. char[x]).
  261.  
  262.   With this library, nearly all of these problems are eliminated.
  263.   Being a higher level set of functions and operators, the
  264.   applications programmer spends a great deal less time worrying about
  265.   how the strings are stored and maintained and is given more time to
  266.   solving the problem at hand.
  267.  
  268.   Expanding an earlier example:
  269.  
  270.   (Example 1.2.2)
  271.  
  272.   The purpose here is to assign a string to all three strings and then
  273.   concatenate them all together, storing the result in the first
  274.   string.
  275.  
  276.   ANSI C, style 1
  277.  
  278.   1  |  char S1[18];
  279.   2  |  char S2[13];
  280.   3  |  char* S3=" mice.";
  281.   4  |  strcpy(S1,"Three");
  282.   5  |  strcpy(S2," blind");
  283.   6  |  strncat(S1,strncat(S2,S3,sizeof(S2)),sizeof(S1));
  284.  
  285.   ANSI C, style 2
  286.  
  287.   11 |  char S1[18];
  288.   12 |  char* S2=" blind";
  289.   13 |  char* S3=" mice.";
  290.   14 |  strcpy(S1,"Three");
  291.   15 |  sprintf(S1,"%s%s%s",S1,S2,S3);
  292.  
  293.   C++ with Strings library
  294.  
  295.   21 |  String S1="Three";
  296.   22 |  String S2=" blind";
  297.   23 |  String S3=" mice.";
  298.   24 |  S1+=S2+S3;
  299.  
  300.   Note that in lines 1 and 2, the applications programmer needed to
  301.   decide whether char* or char[x] could be used and, if the latter,
  302.   how much storage was going to be needed.  In style 1, S2 needed to
  303.   be defined as an array because part of the concatenation process was
  304.   going to involve storing a concatenated result in S2.  There were
  305.   ways to avoid this while still avoiding the use of sprintf such as
  306.   concatenating S1 to S2 and then S1 to S3.  On those lines where
  307.   "char* S=" was used, "static char S[]=" could have been used.  Also,
  308.   the programmer could choose to use strcat instead of strncat and
  309.   thus avoid the use of sizeof, but if they modified some code, they
  310.   may forget to expand their arrays and overwrite memory. On the other
  311.   hand, sometimes when a programmer types in one of these function
  312.   calls they insert the wrong variable into sizeof and the problems
  313.   may not show up till years later.  In style 2, not only is there the
  314.   same allocation problem for S1, but there is also the issue of
  315.   memorizing the use of sprintf:  The parameter order and the effects
  316.   of special characters in the form string. Also, modifications beg
  317.   for runtime crashes:  If another string is needed and specified in
  318.   the form string as "%s%s%s%s" yet the new parameter is not added,
  319.   this can result in many, less than predictable results.  These are
  320.   all things that the programmer must always consider when
  321.   manipulating strings in C.
  322.  
  323.   In C++, using this library, the applications programmer has no *need*
  324.   to worry about the declaration size of a string:  Resizing is done
  325.   dynamically.  Any sort of modification can be made to this piece of
  326.   code as far as adding new strings and the like without having to be
  327.   sure to change the code somewhere else too.
  328.  
  329. 1.2.3 more readable
  330.  
  331.   Although readability is known in programming circles as a "religious
  332.   issue", I think many (if not all) programmers can agree that this
  333.   library is more readable than any library that can be created in
  334.   ANSI C.
  335.  
  336.   Strings are treated a great deal more like other built-in (atomic)
  337.   types of C, such as numbers.  Therefore they do not carry all of the
  338.   exceptions that ANSI C string structures (which are a combination of
  339.   two atomic types: the char and the pointer) do.  Further, defining
  340.   the object as a String better clarifies the intent. "String S;" says
  341.   that S is a string, whereas "char* S;" says that S is a pointer to a
  342.   character which the programmer must know can be used to handle a
  343.   string or, more simply, as a pointer to a single char or an array of
  344.   chars that is not to be used as a string.
  345.  
  346.   From example 1.2.2:
  347.  
  348.     ANSI C, style 1, line 6
  349.     strncat(S1,strncat(S2,S3,sizeof(S2)),sizeof(S1));
  350.  
  351.     ANSI C, style 2, line 15
  352.     sprintf(S1,"%s%s%s",S1,S2,S3);
  353.  
  354.     C++ with Strings library, line 24
  355.     S1+=S2+S3;
  356.  
  357.   Just comparing these three lines of code in size tells you that the
  358.   first two are going to take longer to read than the last just
  359.   because there are more characters (Their size, in characters, is 49,
  360.   30 and 10, respectively). In the first line, there are two function
  361.   calls (strncat), two operator calls (sizeof), two of the variables
  362.   are referenced twice and a whole mess of parentheses.  In the second
  363.   line there are two references to S1 and the form string ("%s%s%s")
  364.   which, when debugging, needs to be compared to the following
  365.   parameters to be sure that there are the same number of parameters
  366.   as "%s"s.  I think that the last line is about as plain and easy to
  367.   understand as it could get.  What is happening is very quick to read
  368.   and easier to understand.  There is no place in this line that a
  369.   conflicting error could occur (such as a sizeof on the wrong var in
  370.   the first line or a "%s" without a matching argument in the second).
  371.  
  372. 1.2.4 eliminate overflow errors
  373.  
  374.   An ANSI C string programming problem that is pretty hard to track
  375.   down is when a user feeds a program a string that is bigger than the
  376.   applications programmer expected to have that string ever hold.  The
  377.   result is that data is written where other data is supposed to be
  378.   stored.  This can lead to anything from some garbled data to a
  379.   system crash.
  380.  
  381.   By using the "String" type of this library, this problem is avoided.
  382.   when an attempt is made to store more string than will fit into the
  383.   current allocation, more space is allocated and the string is stored
  384.   there.
  385.  
  386. 1.2.5 faster executable
  387.  
  388.   I have to admit that generally, this string stuff has a slight speed
  389.   overhead.  However, there is at least one case where speed can
  390.   obviously be improved:  The length of the string is always known and
  391.   does not need to be calculated.
  392.  
  393.   A good example of where this pays off is in a loop where the
  394.   programmer wants to examine every character in a string.
  395.  
  396.   In C:
  397.  
  398.   char* S;
  399.   ...
  400.   for(I=0;I<strlen(S);I++)
  401.   ...
  402.  
  403.   In C++ with this library
  404.  
  405.   String S;
  406.   ...
  407.   for(I=0;I<S.Len();I++)
  408.   ...
  409.  
  410.   In the first example, the length of the string is re-calculated with
  411.   every pass through the loop whereas in the second example the string
  412.   length is retrieved from a value stored in memory.  Of course, an
  413.   alert C programmer can repair the problem with the first example by
  414.   storing the length in a temporary variable before the loop is
  415.   executed.
  416.  
  417.   Other than that, what would save execution time is fewer function
  418.   calls with shorter, fewer parameters.
  419.  
  420. 1.2.6 use less memory
  421.  
  422.   Again, don't misinterpret this:  There's also a slight memory
  423.   overhead in most cases.  The exceptions are that:  Programmers don't
  424.   need to over allocate memory to cover "worst case";  fewer function
  425.   calls with fewer parameters make for less code space.
  426.  
  427.   For example, say a string is passed to a function that can be any
  428.   size from 5 to 1005 and the first thing that needs to be done is to
  429.   make a local copy of that string.  Also, the function is going to
  430.   modify the string such that it may grow and shrink within a range of
  431.   5 to 2005 chars.  In C, the proper thing to do is to allocate a
  432.   chunk of memory that can hold 2005 characters.  With this library
  433.   you just assign the given string to a new one and the new string
  434.   will automatically be the current size and as modifications are
  435.   made, it will grow as needed.  If most calls to this function pass
  436.   strings of length 10 and have internal strings resulting in a length
  437.   of 15, then the C stuff will have wasted almost 2000 bytes of memory
  438.   while this library will be using just a few bytes over 15.
  439.  
  440. 1.2.7 functions that are more independent (don't need storage space)
  441.  
  442.   If you write a function that returns a string in ANSI C, then you
  443.   first need to receive a pointer to a place in memory where you can
  444.   store the resulting string.  In C++ with this library, you can just
  445.   return a "String" object without first being passed a chunk of
  446.   memory.  For example, say I want a function called Str, that when
  447.   passed an integer, would return a string.  A possibility in C is
  448.   "char* Str(long Num, char* S)".  When calling this function, the
  449.   programmer must allocate enough space to store the resulting string
  450.   and pass a pointer to this area via the second parameter.  That same
  451.   pointer will be returned on exit.  This is a lot of extra hassle for
  452.   the applications programmer. In C++ with this library you can have
  453.   "String Str(long Num)".  The storage space is created dynamically
  454.   and the result is passed to whatever does the calling.  The
  455.   applications programmer does not need to bother with preparing
  456.   storage space for the result.
  457.  
  458. 2 Disadvantages from C
  459.  
  460.   I think that 95% of the time, the advantages of using this library
  461.   far outweigh the disadvantages.  Also, I think, 99% of the time,
  462.   the disadvantages are negligable, non-existent or compensated for.
  463.   Note that as a programmer becomes more familiar with this library,
  464.   there are ways to optimize a mix between this code and the
  465.   old char* stuff for better performance and space savings.
  466.  
  467. 2.1 speed overhead
  468.  
  469.   Every time a string is created and sometimes when a string is
  470.   expanded in size, memory needs to be allocated.  When the string is
  471.   disposed of, that memory needs to be reclaimed.  This memory
  472.   management does take up time.  Also, several of the functions need
  473.   to take a little time to modify a local variable to keep track of
  474.   the length.
  475.  
  476. 2.2 storage overhead
  477.  
  478.   Not only does a "String" store all that a "char[]" does, it also
  479.   keeps an extra pointer and two integers (keep in mind that with any
  480.   C++ class, how an object is stored and its methods may change).  A
  481.   large array of short strings would probably save a lot of space if
  482.   the char* type was used instead of the String type.
  483.  
  484. 3 A little bit about how this works
  485.  
  486.   Keep in mind that while the interface to this library will probably
  487.   weather time pretty well, always be prepared for some changes.  How
  488.   it works internally probably *will* change although some of the
  489.   concepts may stay the same.  As with any C++ class library, you may
  490.   depend on the interface staying the same, but *never* depend on the
  491.   internal workings and storage staying the same:  If you happen to
  492.   discover how things are stored and processed internally and access
  493.   those values or methods directly, you'll probably regret it later.
  494.   Now, although I'm about to explain how some of the internal stuff
  495.   works, this is to help you decide how to best optimize your own
  496.   code, not so that you can modify this library or its private data.
  497.  
  498.   When a String is declared
  499.  
  500.     String S="Foo";
  501.  
  502.   8 bytes are taken up on the stack and 19 are taken up on the heap.
  503.   The C++ heap management system may also have taken up some memory
  504.   for housekeeping so that the heap memory can be cleanly reclaimed.
  505.   Some time is taken to do the heap allocation, to record the length
  506.   of the string, the amount of memory allocated, the location of the
  507.   heap storage space and then to copy the string constant into the
  508.   heap with the null terminator.
  509.  
  510.   Now, say we append to this string
  511.  
  512.     S+="Bar";
  513.  
  514.   The string constant, with its null terminator, is quickly copied
  515.   into the heap immediately after "Foo" and the string length status
  516.   is incremented by 3.  There are now 12 bytes free on the heap
  517.   already allocated for use for this string.  6 bytes of the heap
  518.   space is used for the string and 1 is used for the null terminator.
  519.  
  520.     S+=" is derived from the acronym FUBAR.";
  521.  
  522.   The concatenation function recognizes that the amount of memory
  523.   needed to store the resulting string is 40 bytes.  19 is currently
  524.   allocated.  55 bytes of a new storage area is allocated.  The text
  525.   "FooBar" is copied from the old storage area to the new storage
  526.   area. The string constant, with its null terminator, is now copied
  527.   into the new storage area following "FooBar".  The old storage area
  528.   is released back to the heap.  The local storage area pointer is set
  529.   to point at the new storage area.  The size of the new storage area
  530.   is recorded.  The length status is incremented to 39.
  531.  
  532. 4 Implementing this with char* for optimal performance
  533.  
  534.   By reading the previous section on how the internals of this library
  535.   work, it should be clear that declaring a string of type String that
  536.   is initialized and referenced, yet never modified, may be a waste of
  537.   time and space.  Say you have a small bit of code:
  538.  
  539.     void Foo(const char*);
  540.     void Bar(const char*);
  541.     ...
  542.     String S="DooDah";
  543.     Foo(S);
  544.     Bar(S);
  545.  
  546.   When S is constructed, it takes some time and space to get set up
  547.   and then just passes a pointer to its local copy of "DooDah" to Foo
  548.   and Bar.  If S were set up as
  549.  
  550.     char* S="DooDah";
  551.  
  552.   instead, then there would be absolutely no time or space spent on
  553.   construction.  S would be calculated at compile time rather than run
  554.   time and is the exact type as what is asked for so there is no
  555.   conversion time to speak of.  The result is a smaller and faster
  556.   program without much loss of readability.
  557.  
  558. 5 Functions
  559.  
  560.   This library provides the same two flavors of functions that most
  561.   C++ class libraries do:  Member functions and non-member functions.
  562.   The big difference is that member functions are called through their
  563.   string object (like S.Left(3)) while non-member functions are called
  564.   directly (like LeftText(S,3)).  Operators, which are a form of a
  565.   function, like '+', '=' and '<', kinda look and act like they're
  566.   non-member functions, but are usually member functions cuz when the
  567.   C++ compiler sees them it will usually break them into a member
  568.   function of one of the operands: "S1<S2" will get thrown into
  569.   something that looks like "S1.LessThan(S2)" (or, more realistically,
  570.   "S1.operator<(S2)").
  571.  
  572. 5.1 String class member functions
  573.  
  574.   The main thing to remember when using these functions and operators
  575.   is that it should *seem* to be the way that you want to manipulate
  576.   the string.  If you're just getting started you might try looking at
  577.   sections 5.1.1, 5.1.3 and then using the library.  After using it a
  578.   bit, come back and read the rest so that you can get more
  579.   functionality and perhaps optimize things a bit more.
  580.  
  581. 5.1.1 declaring a String
  582.  
  583.   Don't let all of these extra operators for constructing a String
  584.   scare you off.  These are mostly just extra whistles and bells
  585.   provided for optimizing existing code.  For the most part, all of
  586.   your string declarations will probably be of the form
  587.  
  588.     String S1="some text";  // S1 is now "some text"
  589.     String S2='X';          // S2 is now "X"
  590.     String S3="";           // S3 is now empty
  591.     String S4=S1;           // S4 is now "some text"
  592.     String S5=S1+S2;        // S5 is now "some textX"
  593.  
  594. 5.1.1.1 based on a given string constant or char*
  595.  
  596.   This is the String constructor that will probably be used more than
  597.   all the others combined.  Maybe even as much as 95% of the time.
  598.   Although the preferred syntax is
  599.  
  600.     String S="some text";
  601.  
  602.   the syntax
  603.  
  604.     String S("some text");
  605.  
  606.   may also be used.
  607.  
  608. 5.1.1.2 based on a character
  609.  
  610.   Initializing a String to a single character may be done with either
  611.   of these two formats
  612.  
  613.     String S1='x';
  614.     String S2('x');
  615.  
  616.   the preferred method being the first.  To initialize a string to a
  617.   certain length stuffed with a certain character, you must use the
  618.   second method followed by the length you want the string to be:
  619.  
  620.     String S3('x',5);  // S3 is now "xxxxx"
  621.  
  622. 5.1.1.3 based on another String
  623.  
  624.   "String S2=S1;"  or  "String S2(S1);" where S1 is predeclared of
  625.   type String.
  626.  
  627. 5.1.1.4 without initialization
  628.  
  629.   I think that
  630.  
  631.     String S="";
  632.  
  633.   is the best notation, although
  634.  
  635.     String S;
  636.  
  637.   can also be used.
  638.  
  639.   Don't use
  640.  
  641.     String S();
  642.  
  643.   cuz the compiler will think that you have just declared a function
  644.   called "S" that takes no parameters and returns a String.
  645.  
  646. 5.1.1.5 extra allocation
  647.  
  648.   This feature is provided ONLY as an optimization technique.  It
  649.   should not be used for all programming, especially by those just
  650.   starting out. Although using it does no harm, it adds more to read
  651.   in the program and thus makes the program less readable to the
  652.   beginner.  I advise not using this feature except in those areas
  653.   where the time or space savings are crucial ("The fastest algorithm
  654.   can frequently be replaced by one that is almost as fast and much
  655.   easier to understand" -- ACM programming pearls).
  656.  
  657.   When a string is constructed, a piece of memory is allocated to
  658.   store the actual string.  Generally, a little more memory than what
  659.   is immediately needed is provided in case the string does a little
  660.   growing.
  661.  
  662.   Should the programmer decide that time is a critical element and
  663.   knows that a string will be expanded beyond it's initial size by,
  664.   say, 30 characters, they may specify in the String constructor that
  665.   room for 30 extra characters needs to be allocated so that the
  666.   string won't need to be re-allocated later.
  667.  
  668.   Another case is when the space is a critical element and the
  669.   programmer knows that the string will not become any larger.  It can
  670.   then be specified in the String constructor that no additional room
  671.   for growth should be allocated.
  672.  
  673.   The above 4 constructors may all be expanded to have an additional
  674.   parameter that will say how much more space should be allocated at
  675.   initialization time.  The following examples all show an additional
  676.   allocation for 30 characters.
  677.  
  678.     1:  String S("some text",30);
  679.       In this example, re-allocation will not occur until the string
  680.       grows beyond 39 characters in size.
  681.  
  682.     2:  String S('x',5,30);
  683.       Note here that three parameters are required to achieve extra
  684.       allocation.  If you want to initialize your string to a single
  685.       character with thirty extra characters worth of memory allocated
  686.       you must use ('x',1,30).  ('x',30) will initialize a string of
  687.       30 'x's and the default extra allocation.
  688.  
  689.     3:  String S(S2,30);
  690.     4:  String S(30);
  691.  
  692.   At this writing, the default amount of extra allocation is 15
  693.   characters. This will probably change as time passes and this
  694.   library becomes implemented on different systems.
  695.  
  696.   Keep in mind that the amount of memory allocated to hold a string is
  697.   different from the length of the string (which is always shorter).
  698.   Also keep in mind that when referring to the amount of memory
  699.   allocated, that value is strictly for string text, not a null
  700.   terminator, a length indicator or any other information.  When a
  701.   String is allocated for 3 characters and is assigned to be "abc",
  702.   re-allocation does not occur.
  703.  
  704. 5.1.2 Length() or Size()
  705.  
  706.   Prototype:  int Length()
  707.               int Size()
  708.  
  709.   These two functions are very similar, yet care needs to used in
  710.   differentiating between the two.  Both take the same parameters
  711.   (none) and return the same type (int).
  712.  
  713.   Length() works like the ANSI C function strlen.  It returns the
  714.   number of characters in the current string.  This function is much
  715.   faster than strlen.
  716.  
  717.   Size() returns the number of bytes needed to store this string
  718.   object on disk.  This value is generally greater than the value
  719.   returned by Length() and the amount of difference will change for
  720.   different versions of this library on different machines (for
  721.   example, some systems will seperate strings with a carriage return
  722.   while others use a carriage return followed by a line feed).  I
  723.   mention all of this cuz sometimes a programmer may notice a trend
  724.   (perhaps that in their experience Size() has always returned a value
  725.   one greater than Length()) and try to take advantage of it, only to
  726.   have it haunt them later.
  727.  
  728. 5.1.3 + (concatenation)
  729.  
  730.   This is the one thing that I like about this library (and C++) more
  731.   than any other. When you need to concatenate a whole mess of strings
  732.   together, you simply put a "+" between them.  You can even mix
  733.   String types with char* and char types.
  734.  
  735.     char* S1="aa";
  736.     String S2="bb";
  737.     String S3=S1+S2+"cc";  // S3 is now "aabbcc"
  738.  
  739.   The only catch with all this is that a programmer would be tempted
  740.   to do something like
  741.  
  742.     String S3=S1+"cc";  // error!!!
  743.  
  744.   in this case, the compiler tries to first evaluate S1+"cc" which are
  745.   both pointers to a character.  Since pointers are not allowed to be
  746.   added to pointers, the compiler will return an error.  The solution
  747.   is to somehow mix a string into the concatenation list.  In this
  748.   example, the best way would be to first convert S1 to a string
  749.  
  750.     String S3=String(S1)+"cc";  // S3 is now "aacc"
  751.  
  752. 5.1.4 += (appending form of concatenation)
  753.  
  754.   Given
  755.  
  756.     char* S1="aa";
  757.     String S2="bb";
  758.  
  759.   then
  760.  
  761.     S2+=S1;  // S2 is now "bbaa"
  762.  
  763.   however
  764.  
  765.     S1+=S2;  // error!!!
  766.  
  767.   will not work.  Remember that S1 is essentially a pointer.  Trying
  768.   to increment a pointer by an object doesn't make much sense and
  769.   programmers are not allowed to modify or overload operators for
  770.   built-in (atomic) types.
  771.  
  772. 5.1.5 = (assignment) and conversions
  773.  
  774.   Another great thing that this library provides over ANSI C is simple
  775.   string assignment.  With S1 and S2 of type String, "S1=S2" will give you
  776.   two equal, yet unique *Strings*. Modifications to S1 will not alter S2!
  777.   Also strings of type String may take assignment from strings of type
  778.   char*, a character, a character constant or a string constant.
  779.   Respectively:
  780.  
  781.     char* S1="aa";
  782.     char C1='b';
  783.     String S2;
  784.     S2=S1;
  785.     S2=C1;
  786.     S2='c';
  787.     S2="dd";
  788.  
  789.   Conversely, partial access to a String is allowed as char*.  The only
  790.   "catch" is that the user must declare the receiving pointer as type
  791.   "const char*".  This is to protect the internal representation, or
  792.   allocated copy of, the String type string.  Most functions which accept a
  793.   parameter of type char*, specify that parameter prefaced with "const", so
  794.   the string may be passed directly and the converter will automatically
  795.   pass the appropriate pointer without reservations.  Given
  796.  
  797.     void Foo(const char*);
  798.     void Bar(char*);
  799.     String S="bar";
  800.  
  801.   the code "Foo(S)" would be fine, but "Bar(S)" would result in an
  802.   error because S could not be converted.  Since Bar does not specify
  803.   that it will not modify the string that is passed to it, then it may
  804.   do so and thus screw up the handling of S by this library.
  805.  
  806.   Copying a string of type String to a string of type char* should be done
  807.   using the ANSI C strcpy or (preferably) strncpy functions:
  808.  
  809.     String S1="Foo";
  810.     char S2[10];
  811.     strncpy(S2,S1,sizeof(S2));
  812.  
  813. 5.1.6 ==,!=,<,>,<=,>= (comparison)
  814.  
  815.   These operators simply call the ANSI C strcmp function.  They are
  816.   provided for higher readability ("S1<S2" replaces "strcmp(S1,S2)<0").
  817.  
  818. 5.1.7 () or At() (retrieving substrings)
  819.  
  820.   Prototype:  String At(int Index, int Length)
  821.               char At(int Index)
  822.  
  823.   String S1="FooBar";
  824.   String S2=S1(1,3);  //  S2 is now "ooB"
  825.  
  826.   Note that the parens can be prefixed with "At" if desired.  The
  827.   above line could then read
  828.  
  829.     String S2=S1.At(1,3);  //  S2 is now "ooB"
  830.  
  831.   The second parameter is optional.  If it's left out, a single char
  832.   is returned.
  833.  
  834.     String S2=S1.At(3);  //  S2 is now "B"
  835.     char C=S1.At(3);     //  C is now 'B'
  836.  
  837. 5.1.7.1 Before(), Through(), From() and After()
  838.  
  839.   Prototype:  String Before(int Index)
  840.               String Through(int Index)
  841.               String From(int Index)
  842.               String After(int Index)
  843.  
  844.   Four quickie functions that can add a little readability to your
  845.   substring retrieval.
  846.  
  847.     String S1="abcdefghijk";
  848.     String S2=S1.Before(5);   //  S2 is now "abcde"
  849.     String S3=S1.Through(5);  //  S3 is now "abcdef"
  850.     String S4=S1.From(5);     //  S4 is now "fghijk"
  851.     String S5=S1.After(5);    //  S5 is now "ghijk"
  852.  
  853. 5.1.8 [] (String char reference)
  854.  
  855.   Use this just as you would use it on an ANSI C style string.
  856.  
  857.     String S="FooBar";
  858.     S[0]=S[3];  // S is now "BooBar"
  859.  
  860.   This indexing is completely safe.  As could be expected, referencing
  861.   beyond the end of the string will probably not do what you want
  862.   (although all data will remain safe).  If you assign a null ('\0' or
  863.   0) to a character in the string, you will confuse the string
  864.   handler.  If you want to truncate the string, call Left.
  865.  
  866. 5.1.9 Left(), Right(), Center(), Just()  (justification)
  867.  
  868.   Prototype:  void Left(int NewSize)
  869.               void Right(int NewSize)
  870.               void Center(int NewSize)
  871.               void Just(SByte Type, int NewSize)
  872.  
  873.   Left, Right and Center all take one paramater, the new size of the
  874.   string desired.  If the size of the string is larger than the new
  875.   size desired, the right part of the string is truncated.  Otherwise,
  876.   the string is padded with spaces to bring the string up to the new
  877.   size desired.
  878.  
  879.   Examples:
  880.  
  881.     String S="Foo";
  882.     S.Left(1);    //  S is now "F"
  883.     S.Left(3);    //  S is now "F  "
  884.     S="Foo";      //  S is now "Foo"
  885.     S.Right(5);   //  S is now "  Foo"
  886.     S.Right(3);   //  S is now "  F"
  887.     S="Foo";      //  S is now "Foo"
  888.     S.Center(5);  //  S is now " Foo "
  889.  
  890.   The function "Just" simply acts as a parser
  891.  
  892.     S="Foo";
  893.     S.Just(Center,5);  //  S is now " Foo "
  894.  
  895. 5.1.10 Capacity() (report current allocation)
  896.  
  897.   Prototype:  int Capacity()
  898.  
  899.   Simply reports how many characters long the string can get without
  900.   having to re-allocate.
  901.  
  902. 5.1.11 ReAlloc() (change capacity)
  903.  
  904.   Prototype:  int ReAlloc(int NewCapacity)
  905.  
  906.   Will perform a re-allocation to the capacity required.  You might
  907.   use this to prevent future multiple re-allocation.
  908.  
  909. 5.1.12 ToLower() (force all upper case letters to lower case)
  910.  
  911.   Prototype:  void ToLower()
  912.  
  913. 5.1.13 ToUpper() (force all lower case letters to upper case)
  914.  
  915.   Prototype:  void ToUpper()
  916.  
  917. 5.1.14 Index() (find the index of a char)
  918.  
  919.   Prototype:  int Index(char SearchChar, int StartIndex=0)
  920.  
  921.   Starting at StartIndex, the string will be searched until SearchChar
  922.   is found or the end of the string is reached.  If SearchChar is
  923.   found, the function returns the index to the char, otherwise the
  924.   function will return the constant "NotFound".
  925.  
  926. 5.1.15 Insert() (insert a char or a sting into the string)
  927.  
  928.   Prototype:  void Insert(char C,int Index=0)
  929.               void Insert(const char* St,int Index=0)
  930.  
  931.   String S="abcdefghijk";
  932.   S.Insert('X',3);    //  S is now "abcXdefghijk"
  933.   S.Insert("ZZZ",1);  //  S is now "aZZZbcXdefghijk"
  934.   S.Insert("AA");     //  S is now "AAaZZZbcXdefghijk"
  935.     //  S="AA"+S would be more readable I think
  936.  
  937. 5.1.16 Delete() (delete characters from the string)
  938.  
  939.   Prototype:  void Delete(int Index=0,int Length=1)
  940.  
  941.   String S="abcdefghijk";
  942.   S.Delete(1,2);  //  S is now "adefghijk"
  943.  
  944. 5.2 non-member functions
  945.  
  946.   These functions add a lot of coding convenience since they all
  947.   return strings without the need of preallocated space.  They can be
  948.   used directly in functions that ask for a string without having an
  949.   intermediate storage identifier:
  950.  
  951.     void Foo(const char*);
  952.     String Str(long);
  953.     ...
  954.     Foo(Str(10000));
  955.  
  956.   In ANSI C, you would have to first declare a temporary string big
  957.   enough to store the result of "Str", pass the string to "Str" and
  958.   then pass the result, which is stored in your string, to "Foo".
  959.  
  960. 5.2.1 Str() (convert integers to String)
  961.  
  962.   Prototype:  String Str(long)
  963.  
  964.   Examples:
  965.  
  966.     int B=3;
  967.     String S=Str(B);  //  S is now "3"
  968.     S=Str(999999);    //  S is now "999999"
  969.     S=Str(-99999);    //  S is now "-99999"
  970.  
  971. 5.2.2 Form() (convert reals to a String using a format)
  972.  
  973.   Prototype:  String Form(const char* Format,double Val)
  974.               String Form(int FLen,long Val)
  975.  
  976.   You pass a legal format and a number to fit in it, and you'll get a
  977.   string back that is the same length as your format and has your
  978.   number properly arranged in it.
  979.  
  980.   Characters that can be used are:
  981.  
  982.     '#'  a number, or a space if left of decimal, 0 if right
  983.     '@'  same as '#' cept is 0 if there is no number
  984.     '.'  defines the decimal place, if any.  May only be one
  985.     ','  a comma place holder
  986.  
  987.   The characters '<' and '>' may be used to show negation.  They must
  988.   both be used with '<' as the first character in the string and '>'
  989.   as the last.
  990.  
  991.   Examples:
  992.  
  993.     String S=Form("##",12.4);       // S is now "12"
  994.     S=Form("<###,###.##>",-12.4);   // S is now "<     12.40>"
  995.     S=Form("<###,###.##>", 12.4);   // S is now "      12.40 "
  996.     S=Form("@@@@@",        12.4);   // S is now "00012"
  997.     S=Form("@@@@@",       -12.4);   // S is now "-0012"
  998.     S=Form("#####",       -12.4);   // S is now "  -12"
  999.     S=Form("@@@@@.@@",     12.4);   // S is now "00012.40"
  1000.     S=Form("###,###.##",  12345);   // S is now " 12,345.00"
  1001.     S=Form("##",            123);   // S is now "**"
  1002.  
  1003.   The first parameter may also be a number...
  1004.  
  1005.     S=Form( 6, 1234);   // S is now " 1,234"
  1006.     S=Form( 4, 1234);   // S is now "1234"
  1007.     S=Form( 2, 1234);   // S is now "**"
  1008.     S=Form(-6, 1234);   // S is now " 1234 "
  1009.     S=Form(-6,-1234);   // S is now "<1234>"
  1010.     S=Form(-7,-1234);   // S is now "<1,234>"
  1011.     S=Form( 6,-12.3);   // S is now "   -12"
  1012.  
  1013.   If the first parameter is a number, then the second must be an
  1014.   integer (or it will be converted to one).
  1015.  
  1016. 5.2.3 StringOf() (return a string of chars)
  1017.  
  1018.   Prototype:  String StringOf(int HowMany, char OfWhat)
  1019.  
  1020.   To remember the parameters of this think of "I want a string of
  1021.   twenty periods", so you make the function call "StringOf(20,'.')".
  1022.   To help remember the string constructor parameters (a very different
  1023.   thing!), remember that it's based on the char and the number of
  1024.   those chars is optional, so the char must come first.
  1025.  
  1026.   String S=StringOf(5,'x');  //  S is now "xxxxx"
  1027.   String S('x',5);           //  S is now "xxxxx"
  1028.  
  1029. 5.2.4 Spaces() (return a String containing a certain number of spaces)
  1030.  
  1031.   Prototype:  String Spaces(int HowMany)
  1032.  
  1033. 5.2.5 LeftText(), RightText(), CenterText(), JustText()
  1034.  
  1035.   Prototype:  String LeftText(const char* CS, int NewSize)
  1036.               String RightText(const char* CS, int NewSize)
  1037.               String CenterText(const char* CS, int NewSize)
  1038.               String JustText(const char* CS, SByte Type, int NewSize)
  1039.  
  1040.   Remarkably similar to the String member functions Left, Right,
  1041.   Center and Just.
  1042.  
  1043.